% Ejercicio "Evaluación de funciones"
\subsection*{\fbox{\theejercicio} - Evaluaci\'on de funciones}

Construir un analizador sint\'actico que permita evaluar el valor de los siguientes tipos de funciones:

\begin{itemize}
\item Funciones constantes, resultado de varias operaciones aritm\'eticas, con los operadores suma, producto y potencia.

\item Funciones de tipo polinomio, que dependen de una s\'ola variable. Cada t\'ermino del polinomio tiene un coeficiente, el nombre de la variable y el grado, seg\'un el formato \verb@4x^3@. Los distintos t\'erminos se unen mediante el operador suma. La evaluaci\'on de la funci\'on se debe hacer utilizando el valor con el que se llama la funci\'on. Un ejemplo de entrada de este tipo es:

\verb@f(3) = 4x^2 + 1x^1 + 0x^4 + 2x^0;@

\smallskip

Es decir siempre cada t\'ermino que aparece incluye coeficiente y exponente, adem\'as del nombre de la variable. La evaluaci\'on de esta funci\'on es 41.

\item Funciones de tipo polinomio con dos variables. Cada uno de los t\'erminos s\'olo har\'a referencia a una de las dos variables, que se llamar\'an {\tt x} e {\tt y}. La funci\'on tendr\'a dos par\'ametros de entrada separados por una coma. El primer par\'ametro es el valor que debe utilizarse para evaluar los t\'erminos en los que aparace {\tt x} y el segundo de los t\'erminos en los que aparace {\tt y}. Por ejemplo: 

\verb@g(-1,3) = 2y^2 + 4x^3 + 1x^4;@

\smallskip

La evaluaci\'on de esta funci\'on es 15.
\end{itemize}

Para construir el analizador lexicogr\'afico utilizar LEX. Se puede utilizar la especificaci\'on YACC sugerida, en la que se proponen algunas reglas que deber\'an ser completadas. La utilizaci\'on de dicha especificaci\'on no es obligatoria. Puede resolverse en problema con otra gram\'atica distinta a la sugerida.

\smallskip

Ejemplo de entrada y salida que se deber\'{\i}a obtener:

\begin{center}
\begin{tabular}{|l|l|} \hline
Entrada                             & Salida                                 \\ \hline
\verb@h(-1) = 4x^3;@                & {\tt La funci\'on h toma el valor -4}  \\
\verb@f() = 4*5^2 + 3;@             & {\tt La funci\'on f toma el valor 103} \\
\verb@f(2) = 4x^3 + 3x^2;@          & {\tt La funci\'on f toma el valor 44}  \\
\verb@g(1,3) = 2y^1 + 3x^4 + 4x^3;@ & {\tt La funci\'on g toma el valor 13}  \\ \hline
\end{tabular}
\end{center}

Especificaci\'on YACC (incompleta):

\begin{verbatim}
%union{
   int num;
   char id;
   struct{
      int x,val;
   } func1;
   /*COMPLETAR SI SE CONSIDERA NECESARIO*/
}

   /* COMPLETAR */
%type <num> Constante
%type <func1> Func_Una_Var

%%

S : Func
  | S Func
  ;

Func : Func_Constante `;'
     | Func_Una_Var `;' { /*COMPLETAR*/ }
     | Func_Dos_Var `;' { /*COMPLETAR*/ }
;

Func_Constante : ID `(' `)' `=' Constante { /*COMPLETAR*/ }
               ;

Func_Una_Var : /*COMPLETAR*/
             | Func_Una_Var `+' NUM ID `^' NUM 
                      { $$.x=$1.x; $$.val=$1.val+$3*pow($1.x, $6); }
             ;

Func_Dos_Var : /*COMPLETAR CON TODAS LAS REGLAS QUE SEA NECESARIO*/

Constante : NUM { $$=$1; }
          | /*COMPLETAR CON TODAS LAS REGLAS QUE SEA NECESARIO*/
          ;
%%
\end{verbatim}

% Solución del ejercicio
\subsubsection*{SOLUCI\'ON}

\underline{ESPECIFICACI\'ON LEX}:

\begin{verbatim}
%%
-?[0-9]+ {yylval.num=atoi(yytext); return NUM;}
[a-z] {yylval.id=yytext[0]; return ID;}
[=,;()+*^] {return yytext[0];}
[\n \t] {;}
. {printf("ERROR ENTRADA");}
%%
\end{verbatim}

\underline{ESPECIFICACI\'ON YACC}:

\begin{verbatim}
%union{
   int num;
   char id;
   struct{
      int x,val;
   } func1;
   struct{
      int x,y,val;
   } func2;
}

%token <num> NUM
%token <id> ID

%type <num> Constante
%type <func1> Func_Una_Var
%type <func2> Func_Dos_Var

%right `='
%left `+'
%left `*'
%left `^'

%%

S : Func
  | S Func
  ;

Func : Func_Constante `;'
     | Func_Una_Var `;' { printf("%d\n", $1.val); }
     | Func_Dos_Var `;' { printf("%d\n", $1.val); }
;

Func_Constante : ID `(' `)' `=' Constante 
                      { printf("La funcion %c toma el valor %d\n",
                                $1, $5); }
               ;

Func_Una_Var : ID`('NUM`)' `=' NUM ID `^' NUM
                      { printf("La funcion %c toma el valor ", $1);
                                $$.x=$3; $$.val=$6*pow($3, $9); }
             | Func_Una_Var `+' NUM ID `^' NUM 
                      { $$.x=$1.x; $$.val=$1.val+$3*pow($1.x, $6); }
             ;

Func_Dos_Var : ID `(' NUM `,' NUM `)' `=' NUM ID `^' NUM
                      {
                        int var;
                        printf("La funcion %c toma el valor ", $1);
                        if($9==`x') var=$3; else var=$5;
                        $$.x=$3; $$.y=$5;
                        $$.val=$8*pow(var, $11);
                      }
             | Func_Dos_Var `+' NUM ID `^' NUM
                      {
                        int var; if($4==`x') var=$1.x; else var=$1.y;
                        $$.x=$1.x; $$.y=$1.y;
                        $$.val=$1.val+$3*pow(var, $6);
                       }
             ;

Constante : NUM { $$=$1; }
          | Constante `+' Constante { $$=$1+$3; }
          | Constante `*' Constante { $$=$1*$3; }
          | Constante `^' Constante { $$=pow($1, $3); }
          ;
%%
\end{verbatim}